import {defer, designComponent, PropType} from "plain-design-composition";
import {createPlcPropOptions, PlButton, PlcEmitsOptions, PlcScopeSlotsOptions, PlInput, useDialog, useExternalPlc} from "plain-design";
import React from "react";
import {MonacaEditor} from "@/components/monaco/MonacoEditor";
import './PlcMonacoEditor.scss'
import {TableRenderScope} from "plain-design/src/packages/PlTable/plc/utils/plc.type";

export function useMonacoEditor() {
    const $dialog = useDialog()

    const edit = async (initialValue = '', config?: { title?: string, readonly?: boolean }) => {
        const dfd = defer<string | null>()
        const state = {
            text: initialValue
        }
        $dialog({
            title: config?.title,
            status: null,
            dialogProps: {
                contentPadding: false,
                center: true,
                height: null as any,
                width: null as any,
                minHeight: null as any,
                minWidth: null as any,
            },
            render: () => (
                <div style={{width: '80vw', height: '80vh', overflow: 'hidden'}}>
                    <MonacaEditor v-model={state.text} language="typescript"/>
                </div>
            ),
            confirmButton: !config || !config.readonly,
            cancelButton: !config || !config.readonly,
            onConfirm: () => {
                dfd.resolve(state.text)
            },
            onCancel: () => {
                dfd.reject(state.text)
            },
        })

        return dfd.promise
    }

    return {
        edit,
    }
}

export const PlcMonacoEditor = designComponent({
    name: 'plc-textarea',
    props: {
        ...createPlcPropOptions({
            width: 255,
            addEditPadding: true,
        }),
        handlePreview: {type: Function as PropType<(renderScope: TableRenderScope) => void>},
    },
    emits: PlcEmitsOptions,
    scopeSlots: PlcScopeSlotsOptions,
    setup({props, slots, scopeSlots, event}) {

        const monaco = useMonacoEditor()

        const preview = async (renderScope: TableRenderScope) => {
            if (!!props.handlePreview) {
                props.handlePreview(renderScope)
            } else {
                await monaco.edit(renderScope.row[props.field!], {title: props.title, readonly: true})
            }
        }

        const edit = async (row: any) => {
            const newContent = await monaco.edit(row[props.field!], {title: props.title})
            row[props.field!] = newContent
        }

        return useExternalPlc({
            props, scopeSlots, slots, event, defaultScopeSlots: {
                normal: (scope) => !scope.plc.props.field || !scope.row[props.field!] ? null : <span className="plc-monaco-normal-text pl-background-primary" onClick={() => preview(scope)}>{scope.row[props.field!]}</span>,
                edit: ({plc, row}) => !plc.props.field ? null : <PlButton label="编辑" icon="el-icon-edit" onClick={() => edit(row)}/>,
                form: ({plc, row}) => !plc.props.field ? null : <PlInput nativeAttrs={{rows: 4}} textarea v-model={row[plc.props.field]}/>
            }
        })
    },
})
